package com.flying.refdata.batchload.wind.marketdata;


import com.flying.refdata.batchload.wind.ExcelEquityProcessor;
import com.flying.refdata.model.equity.EquityInfo;
import com.flying.refdata.model.equity.MarketData;
import com.flying.refdata.service.EquityService;
import com.flying.refdata.service.MarketDataService;
import com.flying.utils.excel.ExcelUtil;
import com.flying.utils.lang.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
public class ExcelDailyAbstractMarketDataProcessor extends AbstractMarketDataUpdater implements ExcelEquityProcessor<MarketData> {
    private static final int VALID_ROW_INDEX = 1;
    private static final int CODE_COL_INDEX = 0;
    private static final int NAME_COL_INDEX = 1;
    private static final String VALIDATE_CODE = "CODE";
    private static final String VALIDATE_NAME = "NAME";

    private static final int TITLE_ROW_INDEX = 0;
    private static final int MIN_DATA_ROW_INDEX = 2;
    private static final int MIN_DATA_COL_INDEX = 2;

    private static final int INDICATOR_ROW_INDEX = 1;
    private static final String INDICATOR_DATE_REGEX = "\\d{4}-\\d{2}-\\d{2}";
    private static final String INDICATOR_MA_TIMES_REGEX = "\\[周期数\\]\\d+";

    @Autowired
    private EquityService equityService;

    @Autowired
    private MarketDataService dataService;

    @Override
    public boolean isValidSheet(Sheet sheet) {
        return StringUtils.equalsIgnoreCase(VALIDATE_CODE, ExcelUtil.asString(sheet.getRow(VALID_ROW_INDEX).getCell(CODE_COL_INDEX)))
                && StringUtils.equalsIgnoreCase(VALIDATE_NAME, ExcelUtil.asString(sheet.getRow(VALID_ROW_INDEX).getCell(NAME_COL_INDEX)));
    }

    @Override
    public boolean isDataRow(Sheet sheet, Row row) {
        return row.getRowNum() >= MIN_DATA_ROW_INDEX;
    }

    @Override
    public void handleRow(Sheet sheet, Row row) {
        if (!isDataRow(sheet, row)) return;
        Map<String, MarketData> datas = new HashMap<>();
        EquityInfo info = equityService.getOrSaveEquityInfo(ExcelUtil.asString(row.getCell(CODE_COL_INDEX)), ExcelUtil.asString(row.getCell(NAME_COL_INDEX)));
        String title;
        int date;
        for (Cell cell : row) {
            if (ExcelUtil.isEmpty(cell) || cell.getColumnIndex() < MIN_DATA_COL_INDEX) continue;
            title = getTitle(sheet, cell);
            date = getCellRelatedDate(title);
            MarketData curData = datas.get(info.getCode() + date);
            if (curData == null) curData = dataService.getOrCreateMarketData(info, date);
            updateMarketData(curData, sheet, cell);
            if (curData != null) {
                datas.put(info.getCode() + date, curData);
                curData = null;
            }
        }
        flushMarketData(dataService, datas, true);
    }

    @Override
    String getIndicator(Sheet sheet, Cell cell) {
        return ExcelUtil.asString(sheet.getRow(INDICATOR_ROW_INDEX).getCell(cell.getColumnIndex()));
    }

    @Override
    int getMACycles(Sheet sheet, Cell cell) {
        return StringUtil.extractFirstInt(StringUtil.extractFirstString(ExcelUtil.asString(sheet.getRow(TITLE_ROW_INDEX).getCell(cell.getColumnIndex())), INDICATOR_MA_TIMES_REGEX));
    }

    private String getTitle(Sheet sheet, Cell cell) {
        return ExcelUtil.asString(sheet.getRow(TITLE_ROW_INDEX).getCell(cell.getColumnIndex()));
    }

    private int getCellRelatedDate(String title) {
        return Integer.valueOf(StringUtil.extractFirstString(title, INDICATOR_DATE_REGEX).replace("-", ""));
    }
}
